package com.mz.ieann.doplayer.audio.widget

import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Rect
import android.util.AttributeSet
import android.util.Log
import android.view.View
import androidx.annotation.IntDef
import androidx.core.content.ContextCompat
import com.mz.ieann.doplayer.R
import com.mz.ieann.doplayer.audio.AudioHelper

/**
 * <p>------------------------------------------------------
 * <p>Copyright (C) 2020 wasu company, All rights reserved.
 * <p>------------------------------------------------------
 * <p>
 * <p>
 *
 * @author Created by zhangmz
 * @date on 2023/5/12
 */
class YouVisualizerView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyle: Int = 0)
: View(context, attrs, defStyle) {


    /**
     * 音谱源数据
     */
    private var bytes: ByteArray? = null

    /**
     * 波形音谱图描点
     */
    private var points: FloatArray? = null

    /**
     * 绘制的画笔
     */
    private val paint = Paint()

    /**
     * 绘制范围
     */
    private val rect = Rect()

    /**
     * 音谱样式类型
     */
    @VisualizerType
    private var type = VisualizerType.WAVE

    init {
        setBackgroundColor(ContextCompat.getColor(getContext(), R.color.tran))
        setWillNotDraw(false)
        bytes = null
        // 设置画笔的属性
        paint.strokeWidth = 1f
        paint.isAntiAlias = true
        paint.color = ContextCompat.getColor(getContext(), R.color.color_white_FFFFFFFF)
        paint.style = Paint.Style.FILL
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        if (canvas == null || bytes == null || bytes?.size == 0){
            return
        }
        // 使用rect对象记录该组件的宽度和高度
        rect.set(0, 0, measuredWidth, measuredHeight)
        drawVisualizer(canvas, bytes)
    }

    /**
     * 设置音谱图类型
     * @see VisualizerType
     */
    fun setDrawType(@VisualizerType t: Int) {
        type = t
    }

    /**
     * 更新音谱图
     */
    fun updateVisualizer(ftt: ByteArray?) {
        bytes = ftt
        invalidate()
    }

    /**
     * 绘制音谱
     */
    private fun drawVisualizer(canvas: Canvas?, bytes: ByteArray?){
        bytes?.let {
            try {
                canvas?.let {
                    when(type){
                        VisualizerType.WAVE -> drawWaveform(it, bytes)
                        VisualizerType.GRAPH -> drawGraph(it, bytes)
                    }
                }?: Log.v(AudioHelper.TAG, "drawVisualizer, canvas can not be null")
            }catch (e: Exception){
                Log.e(AudioHelper.TAG, "drawVisualizer, draw error:$e")
            }
        }?: Log.e(AudioHelper.TAG, "drawVisualizer, bytes can not be null")
    }

    /**
     * 注解音谱绘制类型
     */
    @IntDef(VisualizerType.WAVE, VisualizerType.GRAPH)
    @Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.CLASS, AnnotationTarget.PROPERTY)
    annotation class VisualizerType{
        companion object{
            const val WAVE = 0
            const val GRAPH = 1
        }
    }

    /**
     * 绘制块状的波形图
     */
    private fun drawWaveform(canvas: Canvas, data: ByteArray){
        for (i in 0 until data.size - 1) {
            val left = (width * i / (data.size - 1)).toFloat()
            // 依据波形值计算该矩形的高度
            val top = (rect.height() - (data[i + 1] + 128).toByte() * rect.height() / 128).toFloat()
            val right = left + 1
            val bottom = rect.height().toFloat()
            canvas.drawRect(left, top, right, bottom, paint)
        }
    }

    /**
     * 绘制曲线波形图
     */
    private fun drawGraph(canvas: Canvas, data: ByteArray){
        // 假设point数组还未初始化
        if (points == null || (points?.size ?: 0) < data.size * 4) {
            points = FloatArray(data.size * 4)//  * 4
        }
        points?.let {
            for (i in 0 until data.size - 1) {
                // 计算第i个点的x坐标
                it[i * 4] = (rect.width() * i / (data.size - 1)).toFloat()
                // 依据bytes[i]的值（波形点的值）计算第i个点的y坐标
                it[i * 4 + 1] = (rect.height() / 2 + (data[i] + 128).toByte() * 128 / (rect.height() / 2)).toFloat()
                // 计算第i+1个点的x坐标
                it[i * 4 + 2] = (rect.width() * (i + 1) / (data.size - 1)).toFloat()
                // 依据bytes[i+1]的值（波形点的值）计算第i+1个点的y坐标
                it[i * 4 + 3] = (rect.height() / 2 + (data[i + 1] + 128).toByte() * 128 / (rect.height() / 2)).toFloat()
            }
            // 绘制波形曲线
            canvas.drawLines(it, paint)
        }?: Log.e(AudioHelper.TAG, "drawGraph, points can not be null")
    }

}